package gwtgaetools.client.ui;

import gwtgaetools.client.ItemManager;
import gwtgaetools.client.OMList;
import gwtgaetools.client.listeners.ListListener;
import gwtgaetools.client.listeners.Listener;
import gwtgaetools.shared.model.BaseObject;
import gwtgaetools.shared.model.ObjectManager;
import gwtgaetools.shared.model.PropertyEnum;

import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.user.client.ui.ListBox;


public class SmartListBox<T extends BaseObject<T, PE>, M extends ObjectManager<T, M, PE>, PE extends PropertyEnum<PE, T>> extends ListBox implements ListListener<M>, Listener<ItemManager<String>> {

	public ChangeHandler changeHandler;

	public OMList<T, M, PE> items;
	
	@Override public void observe(ItemManager<String> tt) {
		if (tt.getItem()!=null) {
			for (int i=0; i<getItemCount(); i++) {
				if (getValue(i).equals(tt.getItem())) {
					setSelectedIndex(i);
					break;
				}
			}
		}
	}

	@Override public boolean add(M m) {
		add(items.size()-1, m);
		return true;
	}

	public void setItems(OMList<T, M, PE> items) {
		this.items = items;
		items.registerListener((ListListener<M>) this);
		addStyleDependentName("enabled");
	}

	@Override
	public void add(int index, M m) {
		final String id = m.getListBoxId().getItem();
		insertItem(m.getListBoxName().getItem(), id, index);
		m.deleteListeners.add(this);
		Listener<ItemManager<String>> tnlc = new Listener<ItemManager<String>>() {

			@Override
			public void observe(ItemManager<String> t) {
				for (int i=0; i<getItemCount(); i++) {
					if (getValue(i).equals(id)) {
						setItemText(i, t.getItem());
						break;
					}
				}	
			}
		};
		m.getListBoxName().registerListener(tnlc, false);
		if (getItemCount()==1 && changeHandler != null)
			changeHandler.onChange(null);
	}

	@Override
	public void delete(M t) {
		M tt = (M) t;
		for (int i=0; i<getItemCount(); i++) {
			if (getValue(i).equals(tt.getListBoxId().getItem())) {
				removeItem(i);
				break;
			}
		}	
	}
	
	public M selected() {
		return items.getById(getValue(getSelectedIndex()));
	}
	
	public void setSelected(M t) {
		for (int i=0; i<getItemCount(); i++) {
			if (getValue(i).equals(t.id.getItem())) {
				setSelectedIndex(i);
				break;
			}
		}
	}

	@Override public void updateIndex(M t, int i, int prevI) {
		if (getValue(prevI).equals(t.id.getItem())) {
			boolean setNewIndex = false;
			if (getSelectedIndex()==prevI)
				setNewIndex = true;

			removeItem(prevI);
			insertItem(t.getListBoxName().getItem(), t.id.getItem(), i);
			
			if (setNewIndex)
				setSelectedIndex(i);
		}
		
	}

}
